package cn.yuanqiao.archive.Identify.service.impl;


import cn.yuanqiao.activiti.domain.ActivitiPackage;
import cn.yuanqiao.activiti.service.RemoteActivitiService;
import cn.yuanqiao.archive.Identify.domain.YqMjApprove;
import cn.yuanqiao.archive.Identify.mapper.MjIdentifyMapper;
import cn.yuanqiao.archive.Identify.mapper.YqMjApproveMapper;
import cn.yuanqiao.archive.Identify.service.BgqxLcIdentifyService;
import cn.yuanqiao.archive.appManager.domain.TenantCategory;
import cn.yuanqiao.archive.appManager.mapper.TenantApplyMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantCategoryMapper;
import cn.yuanqiao.common.constant.Constants;
import cn.yuanqiao.common.core.domain.R;
import cn.yuanqiao.common.enums.DbIdEnum;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.DateUtils;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.common.utils.StringUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.config.YqDatabaseIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ProjectName: JZSDAS
 * @Package: cn.yuanqiao.archive.Identify.service.impl
 * @ClassName: BgqxLcIdentifyServiceImpl
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2023/12/6 9:25
 * @Version: 1.0
 */
@Service
public class BgqxLcIdentifyServiceImpl implements BgqxLcIdentifyService {

    @Autowired
    private TenantApplyMapper tenantApplyMapper;

    @Autowired
    private TenantCategoryMapper tenantCategoryMapper;

    @Autowired
    private MjIdentifyMapper mjIdentifyMapper;

    @Autowired
    private RemoteActivitiService remoteActivitiService;

    @Autowired
    private YqMjApproveMapper yqMjApproveMapper;

    @Autowired
    private YqDatabaseIdProvider yqDatabaseIdProvider;

    private String dataBaseId;

    @PostConstruct
    public void getDatabaseId() {
        dataBaseId =  yqDatabaseIdProvider.getDatabaseId();
    }
    /**
     * 审核通过后修改密级
     *
     * @return
     */
    @Transactional
    @Override
    public int updateBgqxType(String id) {
        YqMjApprove yqMjApprove = yqMjApproveMapper.selectYqMjApproveByID(id, new YqMjApprove().getTableName());
        //todo  通过审批 修改档案信息密级状态  并更新关联表信息
        updateData(yqMjApprove.getFilesId(), yqMjApprove.getCategoryId(), yqMjApprove.getType(), yqMjApprove.getMjType());
        yqMjApprove.setState("2");
        yqMjApprove.setTask("1");
        yqMjApproveMapper.updateYqMjApprove(yqMjApprove, new YqMjApprove().getTableName());
        return 1;
    }

    /**
     * 审批未通过
     *
     * @param id
     * @return
     */
    @Override
    public int disagreeBgqxType(String id) {
        YqMjApprove yqMjApproveDate = yqMjApproveMapper.selectYqMjApproveByID(id, new YqMjApprove().getTableName());
        StringBuilder sql = new StringBuilder("");
        sql.append(" select  IFNULL( BGQX,'-1') AS BGQX from " + yqMjApproveDate.getSubTableName());
        sql.append(" where ID = " + yqMjApproveDate.getFilesId());
        List<Map<String, Object>> mapList = mjIdentifyMapper.selectUnionALLTableData("t.BGQX", sql.toString());
        String bgqx = mapList.get(0).get("BGQX").toString();
        //todo  审批退回后 修改档案信息密级状态  并更新关联表信息
        YqMjApprove yqMjApprove = new YqMjApprove();
        yqMjApprove.setId(id);
        yqMjApprove.setState("2");
        yqMjApprove.setMjType(bgqx);
        yqMjApprove.setTask("0");
        yqMjApproveMapper.updateYqMjApprove(yqMjApprove, yqMjApprove.getTableName());
        return 1;
    }


    /**
     * 调整保管期限接口  先新增到审批表里
     *
     * @param yqMjApprove
     * @return
     */
    @Override
    public int insBgqxType(List<YqMjApprove> yqMjApprove) {
        for (YqMjApprove l : yqMjApprove) {
            l.setId(String.valueOf(SnowflakeIdGenerator.generateId()));
            l.setCreateTime(new Date());
            l.setCreatorId(String.valueOf(SecurityUtils.getUserId()));
            l.setCreator(SecurityUtils.getUsername());
            l.setApproveType("2");
            if ("Y".equals(l.getMjType().toUpperCase()) || "CQ".equals(l.getMjType()) || "DQ".equals(l.getMjType())) {
                continue;
            }
            Integer type = Integer.parseInt(l.getType());
            int max = determineMjType(l);
            if (max != -1) {
                //件
                if (type == 0) {
                    if (Integer.parseInt(l.getMjType().replaceAll("[^\\d]", "")) > max) {
                        throw new ServiceException("卷内件保管期限不能大于卷的保管期限");
                    }
                }
                //组卷
                if (type == 1) {
                    if (Integer.parseInt(l.getMjType().replaceAll("[^\\d]", "")) < max) {
                        throw new ServiceException("卷内件保管期限不能大于卷的保管期限");
                    }
                }
            }
        }
        yqMjApprove.stream().forEach(l -> {
            Map<String, Object> variables = new HashMap<>();
            // variables.put("processVariables", l.toProcessMap());
            variables.put("identifyId", l.getId());
            variables.put("archiveData", Stream.of(l.toProcessMap()).collect(Collectors.toList()));
            R<ActivitiPackage> activitiPackageR = remoteActivitiService.startProcessWsArchiveBGQXIdentify(variables);
            l.setProcessInstance(activitiPackageR.getData().getProcessInstance().getProcessInstanceId());
            l.setState("1");
            yqMjApproveMapper.insertYqMjApprove(l, new YqMjApprove().getTableName());
        });
        return 1;
    }

    /**
     * 取消审批
     *
     * @param
     * @return
     */
    @Override
    public int cancelApproval(String id) {
        //先查审批表数据 判断是否可以取消审批
        YqMjApprove yqMjApprove = yqMjApproveMapper.selectYqMjApproveByID(id, new YqMjApprove().getTableName());
        return yqMjApproveMapper.updateYqMjApproveState(id, new YqMjApprove().getTableName());
    }

    /**
     * 查询审批详情
     *
     * @param
     * @return
     */
    @Override
    public YqMjApprove initiateApproval(String id) {
        //先查审批表数据 判断是否可以取消审批
        YqMjApprove yqMjApprove = yqMjApproveMapper.selectYqMjApproveByID(id, new YqMjApprove().getTableName());
        R<List<ActivitiPackage>> taskByInstanceId = remoteActivitiService.getTaskByInstanceId(yqMjApprove.getProcessInstance());
        String assigned = taskByInstanceId.getData().stream().filter(f -> f.getTask().getStatus().name().equals("ASSIGNED")).map(m -> m.getTask().getId()).collect(Collectors.joining());
        yqMjApprove.setTaskId(assigned);
        return yqMjApprove;
    }

    /**
     * 查询密级审批列表
     *
     * @param yqMjApprove
     * @return
     */
    @Override
    public List<YqMjApprove> YqBgqxApproveList(YqMjApprove yqMjApprove) {
        yqMjApprove.setApproveType("2");
        return yqMjApproveMapper.selectYqMjApproveList(yqMjApprove, new YqMjApprove().getTableName());
    }

    @Override
    public YqMjApprove getYqBgqxApproveByInstanceId(String instanceId) {
        return yqMjApproveMapper.selectYqMjApproveByInstanceId("'" + instanceId + "'", new YqMjApprove().getTableName());
    }

    /**
     * 修改档案信息
     *
     * @param ids        主键id
     * @param categoryId 档案门类id
     * @param type       类型  0 件 1 卷 3 项目
     * @param mjstart    密级状态
     * @return
     */
    public int updateData(String ids, String categoryId, String type, String mjstart) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getLoginUser().getUser().getTenantCode();
        //查询门类信息
        TenantCategory tenantCategory = tenantCategoryMapper.selectTenantCategoryByID(Long.valueOf(categoryId),
                tenantCode + Constants.BIG_TABLE_NAME);
        StringBuilder whereCondition = new StringBuilder();
        //拼接id
        if (StringUtils.isNotEmpty(ids)) {
            String[] idArr = ids.split(",");
            if (idArr.length > 1) whereCondition.append("  in (" + ids + ") ");
            else whereCondition.append(" = ").append(ids);
        }
        StringBuilder sqlSubtable = new StringBuilder();
        String tableName = "";
        String tableNameGeneral = tenantCode;
        String id = "";
        //组件信息
        if (type.equals("0")) {
            //表名
            tableName = tenantCategory.getFileTableName();
            //总表
            tableNameGeneral = tableNameGeneral + Constants.BIG_TABLE_YQDA;
            id = " DA_ID  ";
        }
        //组卷
        if (type.equals("1")) {
            //表名
            tableName = tenantCategory.getFolderTableName();
            //总表
            tableNameGeneral = tableNameGeneral + Constants.BIG_TABLE_YQFOLDER;
            String tableNameFile = tenantCategory.getFileTableName();
            id = " FOLDER_ID  ";
            //处理关联表sql
            sqlSubtable.append(" update " + tableNameFile + " file ");
            sqlSubtable.append("  set file.BGQX = '" + mjstart + "',");
            sqlSubtable.append("  file.JDSJ = '" + DateUtils.getTime() + "' ");
            sqlSubtable.append(" where file.ID in ( ");
            sqlSubtable.append(" SELECT ff.DA_ID FROM " + tenantCode + Constants.BIG_TABLE_FOLDER_NAME + " ff WHERE  ff.FOLDER_ID ");
            sqlSubtable.append(whereCondition);
            sqlSubtable.append(" )");
        }
        StringBuilder sql = new StringBuilder();
        StringBuilder sqlSumTable = new StringBuilder().append(" update " + tableNameGeneral);
        StringBuilder sqlTable = new StringBuilder().append(" update " + tableName);
        sql.append(" set BGQX = '" + mjstart + "', ");
        sql.append(" JDSJ = '" + DateUtils.getTime() + "' ");
        sqlTable.append(sql).append(" where ID " + whereCondition);
        sqlSumTable.append(sql).append(" where  " + id + whereCondition);
        if (!type.equals("3")) {
            mjIdentifyMapper.updateTableData(sqlTable.toString());
            mjIdentifyMapper.updateTableData(sqlSumTable.toString());
        }
        if (sqlSubtable.toString() != null && !"".equals(sqlSubtable.toString())) {
            mjIdentifyMapper.updateTableData(sqlSubtable.toString());
        }
        return 1;
    }


    /**
     * 保管期限判断
     *
     * @param yqMjApprove
     * @return
     */
    public int determineMjType(YqMjApprove yqMjApprove) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getLoginUser().getUser().getTenantCode();
        //查询门类信息
        TenantCategory tenantCategory = tenantCategoryMapper.selectTenantCategoryByID(Long.valueOf(yqMjApprove.getCategoryId()),
                tenantCode + Constants.BIG_TABLE_NAME);
        Integer type = Integer.parseInt(yqMjApprove.getType());
        StringBuilder sqlSubtable = new StringBuilder();
        String tableName = null;
        //件
        if (type == 0) {
            if (tenantCategory.getType() != 0) {
                tableName = tenantCategory.getFolderTableName();
                //处理关联表sql
                sqlSubtable.append(" select  file.ID,IFNULL( file.BGQX,'-1') AS BGQX ,file.jdsj,file.rq from " + tableName + " file ");
                sqlSubtable.append(" where file.ID in ( ");
                sqlSubtable.append(" SELECT ff.FOLDER_ID FROM " + tenantCode + Constants.BIG_TABLE_FOLDER_NAME + " ff WHERE  ff.DA_ID = ");
                sqlSubtable.append(yqMjApprove.getFilesId());
                sqlSubtable.append(" )");
            }
        }
        //组卷
        if (type == 1) {
            tableName = tenantCategory.getFileTableName();
            //处理关联表sql
            sqlSubtable.append(" select file.ID,IFNULL( file.BGQX,'-1') AS BGQX,file.rq from " + tableName + " file ");
            sqlSubtable.append(" where file.ID in ( ");
            sqlSubtable.append(" SELECT ff.DA_ID FROM " + tenantCode + Constants.BIG_TABLE_FOLDER_NAME + " ff WHERE  ff.FOLDER_ID = ");
            sqlSubtable.append(yqMjApprove.getFilesId());
            sqlSubtable.append(" )");
        }
        int max = -1;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(sqlSubtable.toString())) {
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String nowdate = sdf.format(date);
            String bgqxgqsql = "";
            if(dataBaseId.equalsIgnoreCase(DbIdEnum.OSCAR.getCode())){
                bgqxgqsql = " AND ( t.id NOT IN (SELECT id FROM (SELECT id, replace(bgqx, 'D', '') " +
                        " AS bgqxnum, bgqx, rq, jdsj, to_char(to_date((CASE WHEN jdsj IS NULL THEN (CASE WHEN rq is not null " +
                        " THEN rq ELSE '19000101' END) ELSE jdsj END), case when locate('-',(CASE WHEN jdsj IS NULL THEN (CASE WHEN rq IS NOT NULL THEN rq ELSE '19000101' END ) ELSE jdsj END))!=0 then 'YYYY-MM-DD' else 'YYYYMMDD' END),'YYYYMMDD')  AS formatrq, (to_char(to_date((CASE WHEN jdsj " +
                        " IS NULL THEN (CASE WHEN rq is not null THEN rq ELSE '19000101' END) ELSE jdsj END), case when locate('-',(CASE WHEN jdsj IS NULL THEN (CASE WHEN rq IS NOT NULL THEN rq ELSE '19000101' END ) ELSE jdsj END))!=0 then 'YYYY-MM-DD' else 'YYYYMMDD' END) + replace(bgqx, 'D', '') * 365,'YYYYMMDD'))" +
                        " AS gqsj FROM " + tableName + " WHERE   bgqx not in ('Y','DQ','CQ')) WHERE gqsj <= '" + nowdate + "')) ";
            }else{

                bgqxgqsql = " AND ( t.id NOT IN (SELECT id FROM (SELECT id, replace(bgqx, 'D', '') " +
                        " AS bgqxnum, bgqx, rq, jdsj, DATE_FORMAT((CASE WHEN jdsj IS NULL THEN (CASE WHEN (isdate(rq)) = 1 " +
                        " THEN rq ELSE '19000101' END) ELSE jdsj END), 'YYYYMMDD')  AS formatrq, (DATE_FORMAT((CASE WHEN jdsj " +
                        " IS NULL THEN (CASE WHEN (isdate(rq)) = 1 THEN rq ELSE '19000101' END) ELSE jdsj END), 'YYYYMMDD') + replace(bgqx, 'D', '') * 10000)" +
                        " AS gqsj FROM " + tableName + " WHERE bgqx not in ('Y','DQ','CQ')) WHERE gqsj <= '" + nowdate + "')) ";
            }
            List<Map<String, Object>> mapList = mjIdentifyMapper.selectUnionALLTableDataTiaojian(" t.ID,t.BGQX ", sqlSubtable.toString(),bgqxgqsql);
            if (null != mapList && mapList.size() > 0) {
                max = mapList.stream().collect(Collectors.summarizingInt(c -> Integer.parseInt(
                        c.get("BGQX").toString().toUpperCase()
                                .replaceAll("D", "")
                                .replaceAll("Y", "99999")
                ))).getMax();
            }
        }
        return max;
    }
}
